import {def} from "./index";
import {observe} from "./observer";
import {Dep} from "./dep";

// 数组原型方法
const arrayPrototype = Array.prototype;

// 会导致数据变化的数组方法
const ARRAY_FUNC = [
    'push',
    'pop',
    'shift',
    'unshift',
    'splice',
    'sort',
    'reverse'
];

/**
 * 遍历数组的值，并对这些值进行观察
 * @param value
 */
export function walkArray (value) {
    // 为数组的修改方法添加响应式变化
    methodsToPatch(value);
    // 为每一个数组成员
    for (let i=0; i<value.length; i++) {
        observe(value[i]);
    }
}

/**
 * 对于数组的更新使用 数组方法来进行重新观察
 * @param instance
 */
export function methodsToPatch (instance) {
    ARRAY_FUNC.forEach(
        function (method) {
            def(instance, method, function decorator (...args) {
                const original = arrayPrototype[method];
                let result = original.apply(instance, args);
                const observer = instance.__ob__;
                let inserted = undefined;
                switch (method) {
                    case ('shift'):
                    case ('push'): {
                        inserted = args[0];
                        break;
                    }
                    case ('splice'): {
                        inserted = args.splice(0, 2);
                        break;
                    }
                }
                if (inserted) {
                    observe(inserted);
                }
                observer.dep.notify();
                return result;
            });
        }
    );
}
